#include "Httpserver.hpp"
#include "error.hpp"
#include "log.hpp"
#include "util.hpp"
#include <memory>
#include <sstream>
#include <vector>
const std::string SEP = "\r\n";
const std::string curdirector = "./wwwroot";
const std::string defaultdirector = "./wwwroot/file2.html";
const std::string page_404 = "./wwwroot/404.html";
class Request
{
public:
    void Print()
    {
        log_(ErrorLevel::Debug, "method: %s url: %s httpversion: %s ", method_.c_str(), url_.c_str(), httpversion_.c_str());
        log_(ErrorLevel::Debug, " path_: %s suffix_: %s", path_.c_str(), suffix_.c_str());
        for (auto e : body_)
        {
            cout << e;
        }
    }
    Log log_;
    std::string method_;
    std::string url_;
    std::string path_;
    std::string httpversion_;
    std::vector<std::string> body_;
    std::string suffix_;
};
void Phrase(const std::string &firstline, std::string *method, std::string *url, std::string *httpversion)
{
    stringstream ss(firstline);
    ss >> *method >> *url >> *httpversion;
}
Request deserialize(std::string message)
{
    // 先读取第一行
    int pos = 0;
    Request rq;
    std::string firstline = util::ReadOneline(message, SEP);
    Phrase(firstline, &(rq.method_), &(rq.url_), &rq.httpversion_);
    if (rq.url_ == "/") // 对默认路径'/'做处理
    {
        rq.path_ = defaultdirector;
    }
    else
    {
        rq.path_ = curdirector; //"./wwwroot"
        rq.path_ += rq.url_;    // /file1.html
    }
    int nextpos = rq.path_.rfind(".", rq.path_.size() - 1);
    rq.suffix_ = rq.path_.substr(nextpos, -1);
    while (message.size())
    {
        rq.body_.push_back(util::ReadOneline(message, SEP));
    }
    rq.body_.push_back(util::ReadOneline(message, SEP));
    message.erase(0, -1);
    return rq;
}
std::string GetContentType(const std::string &suffix)
{
    std::string ret = "Content-Type: ";
    if (suffix == ".html" || suffix == ".htm")
        ret += "text/html";
    else if (suffix == ".jpg")
        ret += "image/jpeg";
    return ret + SEP;
}
std::string HttpHead(std::string message)
{
    cout << message << endl;
    // 读到了报文,开始解析报文
    std::string body;
    // 1 请求反序列化
    Request rq = deserialize(message);
    rq.Print();

    // 2 构建响应
    std::string Response;
    if (util::ReadOnefile(rq.path_, &body))
    {
        Response = "HTTP/1.0 200 OK" + SEP;
        Response += "Content-Length: " + std::to_string(body.size()) + SEP;
        Response += GetContentType(rq.suffix_);
        Response += SEP;
        Response += body;
    }
    else // 读取文件失败,返回404页面
    {
        util::ReadOnefile(page_404.c_str(), &body);
        Response = "HTTP/1.404 NoFound" + SEP;
        Response += "Content-Length: " + std::to_string(body.size()) + SEP;
        Response += GetContentType(".html");
        Response += SEP;
        Response += body;
    }
    return Response;
}
//./server + port
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        exit(USAGE_ERR);
    }
    uint16_t port = atoi(argv[1]);
    std::unique_ptr<Httpserver> http(new Httpserver(HttpHead, port));
    http->Init();
    http->start();
    return 0;
}